/*
 * Copyright 2016 jeasonlzy(廖子尧)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.ljwy.gun.okgoHelper;


import com.google.gson.stream.JsonReader;
import com.lzy.okgo.convert.Converter;

import org.json.JSONArray;
import org.json.JSONObject;

import java.io.IOException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

import okhttp3.Response;
import okhttp3.ResponseBody;

/**
 * Created by Sloop on 2018/8/21
 * Description: 解析返回数据
 */
public class JsonConvert<T> implements Converter<T> {

    private Type type;
    private Class<T> clazz;

    public JsonConvert() {
    }

    public JsonConvert(Type type) {
        this.type = type;
    }

    public JsonConvert(Class<T> clazz) {
        this.clazz = clazz;
    }

    /**
     * 该方法是子线程处理，不能相做ui关的工作
     * 主要作用是解析网络返回的 response 对象，生成onSuccess回调中需要的数据对象
     * 这里的解析工作不同的业务逻辑基本都不一样,所以需要自己实现,以下给出的时模板代码,实际使用根据需要修改
     */
    @Override
    public T convertResponse(Response response) throws Throwable {

        if (type == null) {
            if (clazz == null) {
                // 如果没有通过构造函数传进来，就自动解析父类泛型的真实类型（有局限性，继承后就无法解析到）
                Type genType = getClass().getGenericSuperclass();
                type = ((ParameterizedType) genType).getActualTypeArguments()[0];
            } else {
                return parseClass(response, clazz);
            }
        }
        if (type instanceof ParameterizedType) {
            return parseParameterizedType(response, (ParameterizedType) type);
        } else if (type instanceof Class) {
            return parseClass(response, (Class<?>) type);
        } else {
            return parseType(response, type);
        }
    }

    private T parseClass(Response response, Class<?> rawType) throws Exception {
        if (rawType == null) return null;
        ResponseBody body = response.body();
        if (body == null) return null;
        JsonReader jsonReader = new JsonReader(body.charStream());

        if (rawType == String.class) {
            //noinspection unchecked
            return (T) body.string();
        } else if (rawType == JSONObject.class) {
            //noinspection unchecked
            return (T) new JSONObject(body.string());
        } else if (rawType == JSONArray.class) {
            //noinspection unchecked
            return (T) new JSONArray(body.string());
        } else {
            T t = GsonConvert.fromJson(jsonReader, rawType);
            response.close();
            return t;
        }
    }

    private T parseType(Response response, Type type) {
        if (type == null) return null;
        ResponseBody body = response.body();
        if (body == null) return null;
        JsonReader jsonReader = new JsonReader(body.charStream());

        // 泛型格式如下： new JsonCallback<任意JavaBean>(this)
        T t = GsonConvert.fromJson(jsonReader, type);
        response.close();
        return t;
    }

    /**
     * 解析实体类
     *
     * @param response
     * @param type
     * @return
     * @throws IOException
     */

    private T parseParameterizedType(Response response, ParameterizedType type) throws IOException {
        if (type == null) return null;
        ResponseBody body = response.body();
        if (body == null) return null;
        return (T) body.string();
//        Log.d("httpResponse-url", response.request().url().toString());
//        Log.d("httpResponse", str);
//        Type rawType = type.getRawType();                     // 泛型的实际类型
//        Type typeArgument = type.getActualTypeArguments()[0]; // 泛型的参数
//        if (rawType == BaseResponse.class) {
//            BaseResponse baseResponse;
//            if (typeArgument == String.class) {
//                // 泛型格式如下： new JsonCallback<BaseResponse<String>>(this)
//                baseResponse = GsonConvert.fromJson(str, BaseResponse.class);
//            } else {
//                // 泛型格式如下： new JsonCallback<BaseResponse<内层JavaBean>>(this)
//                baseResponse = GsonConvert.fromJson(str, type);
//            }
//            response.close();
//            int code = baseResponse.getCode();
//            String msg = baseResponse.getMsg();
//            if (code == 0) { //约定 正确返回码
//                return (T) baseResponse;
//            } else {
//                //直接抛自定义异常  会出现在 callback的onError中
//                throw new MyException("{\"code\":" + code + ",\"msg\":\"" + msg + "\"}");
//            }
//        } else {
//            throw new MyException("{\"code\":" + 0 + ",\"msg\":\"" + "android端设置返回类型异常" + "\"}");
//        }
    }

}
